package com.tansun.easycare.rule.common.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.kie.api.io.ResourceType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tansun.easycare.rule.codeblock.service.RuleCodeblockService;
import com.tansun.easycare.rule.common.service.RuleGeneralService;
import com.tansun.easycare.rule.decisiontree.entity.DecisionTreeEntity;
import com.tansun.easycare.rule.decisiontree.service.DecisionTreeService;
import com.tansun.easycare.rule.deployonline.entity.RuleDeployment;
import com.tansun.easycare.rule.deployonline.entity.RuleEnterpoint;
import com.tansun.easycare.rule.deployonline.model.RuleDeployVO;
import com.tansun.easycare.rule.deployonline.service.RuleDeployOnlineService;
import com.tansun.easycare.rule.deployonline.service.RuleEnterpointService;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.ruleflow.model.RuleFlowModel;
import com.tansun.easycare.rule.ruleflow.service.RuleFlowService;
import com.tansun.easycare.rule.rulegroup.entity.RuleGroup;
import com.tansun.easycare.rule.rulegroup.model.RuleEditEntity;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.DroolsComplier;
import com.tansun.rule.utils.StringUtils;

@Service("ruleGeneralService")
public class RuleGeneralServiceImpl implements RuleGeneralService {
	
	private final Logger log = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	public DecisionTreeService decisionTreeService;
	@Autowired
	public RuleManageService ruleManageService;
	@Autowired
	public RuleFlowService ruleFlowService;
	@Autowired
	private RuleDeployOnlineService ruleDeployOnlineService;
	@Autowired
	private RuleEnterpointService  ruleEnterpointService;
	@Autowired
	private RuleGroupService ruleGroupService;
    @Autowired
    private RuleCodeblockService ruleCodeblockService;
    
	@Override
	public String saveAndDeployRuleTree(DecisionTreeEntity treeEntity,String serverUrl) throws Exception {
		if(treeEntity.getRuleManage()==null)
			throw new Exception("模型信息为空，如模型名称，项目编号等");
		if(treeEntity.getNodeList()==null)
			throw new Exception("节点信息不存在，请检查");
		if(treeEntity.getNodeList()==null || treeEntity.getResultItems()==null)
			throw new Exception("输出参数信息不存在，请检查");
		//保存决策树
		if(StringUtils.isEmpty(treeEntity.getRuleManage().getId()))
			decisionTreeService.saveOrUpdateDecisionTree(treeEntity.getRuleManage());
		String projectCode = treeEntity.getRuleManage().getProjectCode();
		decisionTreeService.saveOrUpdate(treeEntity);
		ruleManageService.setRuleBaseService(decisionTreeService);
		ruleManageService.publicRule(treeEntity.getRuleManage().getId());//发布决策树
		RuleManage ruleManage = ruleManageService.getById(treeEntity.getRuleManage().getId());
		Map<String,RuleManage> ruleList = new HashMap<String,RuleManage>();
		ruleList.put(treeEntity.getRuleManage().getId(), ruleManage);
		RuleManage ruleFlow = generalRuleFlow(ruleList);
		//发布规则流
		//ruleManageService.setRuleBaseService(ruleFlowService);
		//ruleManageService.publicRule(ruleFlow.getId());
		//生成发布信息
		RuleDeployVO deployVo = new RuleDeployVO();
		RuleDeployment deploy = null;
		RuleEnterpoint pointer = null;
		RuleDeployment condition = new RuleDeployment();
		condition.setManageId(ruleFlow.getId());//新增manageId字段（数据库也要新增）
		List<RuleDeployment> deployList = ruleDeployOnlineService.findList(condition);
		if(deployList!=null && deployList.size()>0) {
			deploy = deployList.get(0);
			RuleEnterpoint enterpoint  = new  RuleEnterpoint();
			enterpoint.setDeploymentId(deploy.getId());
			pointer = this.ruleEnterpointService.findList(enterpoint).get(0);
		}else {
			deploy = new RuleDeployment();
			deploy.setManageId(ruleFlow.getId());
			deploy.setDeployName(ruleFlow.getName());
			deploy.setProjectCode(projectCode);
			deploy.setServerUrl(serverUrl);
			pointer = new RuleEnterpoint();
			pointer.setName(ruleFlow.getName());
			pointer.setCode(com.tansun.rule.utils.StringUtils.getUUID());
			pointer.setControl("on");
		}
		pointer.setRuleflowId(ruleFlow.getCode()+"_"+ruleFlow.getVersion());
		deployVo.setEnterpointList(new ArrayList<RuleEnterpoint>());
		deployVo.getEnterpointList().add(pointer);
		deployVo.setRuleDeployment(deploy);
		ruleDeployOnlineService.saveOrUpdate(deployVo);
		//执行部署
		ruleDeployOnlineService.deployRemoteServer(deployVo.getRuleDeployment().getId(), projectCode);
		return treeEntity.getRuleManage().getId()+"_"+pointer.getCode();
	}
	
	
	private RuleManage generalRuleFlow(Map<String,RuleManage> ruleList) {
		// TODO Auto-generated method stub
		RuleManage tree = ruleList.values().iterator().next();
		RuleFlowModel ruleFlow = new RuleFlowModel();
		ruleFlow.setProjectCode(tree.getProjectCode());
		ruleFlow.setName(tree.getName());
		ruleFlow.setRuleflowInfo(genRuleflowInfo(tree));
		
		RuleManage ruleInfo = new RuleManage();
        ruleInfo.setModelType(RuleModelTypeEnum.RuleFlow.getCode());
        ruleInfo.setName(tree.getName());
        ruleInfo.setProjectCode(tree.getProjectCode());
        List<RuleManage> list = ruleManageService.findList(ruleInfo);
        if(list!=null && list.size()>0){
        	ruleFlow.setCode(list.get(0).getCode());
        	ruleFlow.setManageId(list.get(0).getId());
        }
		try {
			RuleManage ruleManage = ruleFlowService.saveOrUpdate(ruleFlow);
			ruleManageService.setRuleBaseService(ruleFlowService);
            ruleManageService.publicRule(ruleManage.getId());
            ruleManage = ruleManageService.getById(ruleManage.getId());
            return ruleManage;
		} catch (Exception e) {
			log.error("生成规则流报错", e);
			throw new RuntimeException(e);
		}
	}


	private String genRuleflowInfo(RuleManage tree) {
		String json = "{states:{rect1:{type:'start',text:{text:'开始'}, attr:{ x:130, y:146, width:50, height:50}, props:{name:{value:''},metadata:{value:''}}},rect2:{type:'end',text:{text:'结束'}, attr:{ x:650, y:146, width:50, height:50}, props:{name:{value:''},metadata:{value:''},terminate:{value:''}}},rect3:{type:'decisionTree',text:{text:'决策树'}, attr:{ x:366, y:161, width:50, height:50}, props:{name:{value:'决策树'},model:{value:'"
				+ tree.getCode()+"_"+tree.getVersion()
				+ "'}}}},paths:{path2:{from:'rect1',to:'rect3', dots:[],text:{text:'path2'},textPos:{x:0,y:-10}, props:{text:{value:''}}},path3:{from:'rect3',to:'rect2', dots:[],text:{text:'path3'},textPos:{x:0,y:-10}, props:{text:{value:''}}}},props:{props:{layout:{value:''},exception:{value:''},flag:{value:''},name:{value:''},pack:{value:''},lane:{value:'swimName01;swimName02'},itemDefinition:{value:''},version:{value:''}}}}";
		return json;
	}

	@Override
	public void copyRuleItem(String id) throws Exception {
        if(StringUtils.isEmpty(id)){
              throw  new BizException("E-000600");
		}
        // 源规则
		RuleManage ruleManage = this.ruleManageService.get(id);
		
		// 复制规则
    	RuleManage newRuleManage = (RuleManage)BeanUtils.cloneBean(ruleManage);
    	// ruleManage 名称替换 ，日期替换 ，id置空
    	Date date = new Date();
    	newRuleManage.setId(null);
    	// 名称添加随机id防止重复
    	newRuleManage.setName(ruleManage.getName()+"_Copy"+StringUtils.generateShortUuid());
    	newRuleManage.setCode(null);
    	newRuleManage.setVersion(null);
    	newRuleManage.setActiveVersion(null);
    	newRuleManage.setCreateDate(date);
    	newRuleManage.setUpdateDate(date);
    	this.ruleManageService.saveOrUpdate(newRuleManage);
    	
		RuleGroup ruleInfo = new RuleGroup();
		ruleInfo.setManageId(ruleManage.getId());
		ruleInfo.setVersion(ruleManage.getVersion());
		List<RuleGroup> list = this.ruleGroupService.findList(ruleInfo);
		RuleEditEntity ruleEditEntity = new RuleEditEntity();
		ruleEditEntity.setRuleGroups(list);
		this.ruleGroupService.saveOrUpdateRule(newRuleManage,ruleEditEntity);
	}

	@Override
	public String compileDrl(String[] ids) throws BizException {
        if(ids == null || ids.length == 0){
            throw  new BizException("E-000600");
		}
        String resMsg = "";
        List<RuleManage> rmList = this.ruleManageService.findListByIds(Arrays.asList(ids));
        if(rmList!=null&&rmList.size()>0) {
	        String funcContext = ruleCodeblockService.getEffectiveFunc(rmList.get(0).getProjectCode());
			for(RuleManage ruleManage:rmList) {
		        //查询drl文本
				String context = this.ruleGroupService.getRuleDrl(ruleManage);
				DroolsComplier complier = new DroolsComplier();
		
			    complier.addContent(context, ResourceType.DRL);
			    complier.addContent(funcContext, ResourceType.DRL);
			    String msg = complier.complie();
			    resMsg += ruleManage.getName()+":"+msg+"</br>";
			}
        }
		return resMsg;
	}

	@Override
	public void exportRuleItem(String ids) {
		//String[] split = ids.split(",");

	}
}
